home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Presentations / Presentations ’96 / Papers ’96 / Book of Practical Objects / BasicObjects ƒ / CKeywords.h < prev    next >
Encoding:
Text File  |  1996-06-03  |  5.1 KB  |  119 lines  |  [TEXT/CWIE]

  1. //    CKeywords.h
  2. //
  3. //    A base class that stores an arbitrary number of keywords and
  4. //    associated indexes to objects attached to keywords. Multiple
  5. //    indexes are associated with each keyword.
  6. //
  7. //    This class uses Handles to store the keywords in large blocks.
  8. //    It does not provide a way to change the storge mechanism
  9.  
  10. enum {
  11.     kCharsInFirstKeywordlock = 28,
  12.     kMaxKeywordsPerPage = 100,
  13.     kBlockMapKeywordsPerPageLimit = 384,        // NEVER EXCEED THIS ABOVE!!!
  14.     
  15.     kBitsInALong = 32                            // It only seems self-evident
  16. };
  17.  
  18.  
  19. // First of all, we do some tricky stuff with the KeywordHolder
  20. // record. A keyword will usually fit within a single record,
  21. // but if it is longer than 28 bytes, we use the next holder
  22. // block as a continuation block, so the first 4 bytes of that
  23. // block are meaningless. This allows a keyword of 60 bytes to ft
  24. // into just two blocks. The benefit of this scheme is that we can
  25. // preallocate chunks of memory for keyword storage for maximum speed
  26. // but we can still keep the wasted space fairly low. 1000 small keywords
  27. // will only take 32K of memory.
  28.  
  29. typedef    struct {
  30.     short    blockCount;
  31.     short    length;            // bytes of text in this keyword
  32.     char    keywordData[kCharsInFirstKeywordlock];// Pad the keyword size to 32 bytes
  33. } KeywordHolder, *KeywordHolderP, **KeywordHolderH;
  34.  
  35.  
  36. // There is an important note about this structure. The last block
  37. //    (or possibly more) may be left blank if the keyword being added
  38. //    required more blocks than were available in this page.
  39. //    A Page in this context is the header and keywords stored in a
  40. //    single block. It does not actually correspond to a page of VM.
  41.  
  42. typedef    struct    KeywordPage    {
  43.     KeywordPage**    nextPage;        // Handle to next block of keywords
  44.     long            firstKeywordID;    // First ID for this page
  45.     long            keywordsInPage;    // How many occupy this page?
  46.     long            firstFreeSlot;    // First unused block on this page
  47.     long            lastOnPage;        // last used block on the page
  48. //    char            blockMap[kMaxKeywordsPerPage];
  49.     unsigned long    blockMap[12];    // 384 bits, 1 per keyword block (limits
  50.                                     // us to a Maximum page size of 12320 bytes)
  51.     KeywordHolder    keywords[kMaxKeywordsPerPage];
  52. } KeywordPage, *KeywordPageP, **KeywordPageH;
  53.  
  54. //    Reference Info. Each Keyword can be assigned to one or more objects
  55. //    outside this class. When you attach a keyword to an object you can
  56. //    attach the reference inside the CKeywords object. This allows for
  57. //    very fast "searching" for all items with a given keyword. You can
  58. //    just retrieve the references for any given keyword and you are done.
  59. //    The structure for the reference is a user defined number of longs that
  60. //     will be associated with the given keyword.
  61. class    CKeywords
  62. {
  63.     long            fTotalKeywords;
  64.     short            fLongsPerReferenceItem;    // # of longs in a reference
  65.     unsigned short    fReferenceBlockSize;
  66.     KeywordPageH    fFirstKeywordBlock;
  67.     Boolean            fReuseEmptyHoles;        // if false, IDs will not be reused
  68.  
  69. public:
  70.             CKeywords(short longsPerReferenceItem = 1, Boolean reuseHoles = false);
  71.             ~CKeywords(void);
  72.     
  73.     virtual    long    GetKeywordCount(void);
  74.     virtual    long    GetKeywordReferenceCount(long keywordID);
  75. /******************************************************************************/
  76.     virtual    long    GetKeywordReferenceCount(char* theKeyword, short keyLength,
  77.                                             Boolean partialMatch = false);
  78.  
  79.     virtual    long    FindKeywordID(char* theKeyword, short keyLength,
  80.                                     Boolean partialMatch = false);
  81.                 
  82.     virtual    long    FindKeywordIDInRange(long startID, long endID,
  83.                                     char* theKeyword, short keyLength,
  84.                                     Boolean partialMatch = false);
  85.     
  86.     //    Look up a keyword and return the length and data. Be sure you
  87.     //    have enough storage allocted! To just get length, pass nil for
  88.     //    the keyOut parameter.
  89.     virtual    short    GetKeywordByID(long keywordID, char* keyOut);
  90.     
  91.     // The following routines are used to add keywords
  92.     virtual    long    AddKeyword(char* theKeyword, short keyLength);
  93.     virtual    Boolean    AddKeywordReference(long keywordID, long* keyReferenceBlock,
  94.                                         short referenceCount = 1);
  95.     virtual    void    AddReferenceToAllKeywords(long *keyReferenceBlock);
  96.     
  97.     // And of course you might want to delete a keyword
  98.     virtual    void    DeleteKeywordID(long keywordID);
  99.     virtual    void    DeleteKeywordReference(long keywordID, long* keyReferenceBlock);
  100.     virtual    void    DeleteAllReferenceMatch(long *keyReferenceBlock);
  101.     virtual    void    DeleteAllReferences(void);
  102.     
  103.     // Use this with extreme caution! It nukes references, keyword, everything
  104.     virtual    void    DeleteAllKeywords(void);
  105.  
  106. protected:
  107.     virtual    KeywordPageH    CreateEmptyPage(long firstID);
  108.     virtual    Boolean    GetPageN(short whichPage, KeywordPageH *outHand, Boolean createIt);
  109.     virtual    void    FindAvailableSlot(short requiredBlocks, KeywordPageH *outPage,
  110.                                         short *pageIndex, short *pageNumber);
  111.     virtual    short    FindSlotsOnPage(KeywordPageH currentPage, short blocksRequired);
  112.     
  113.     // A current limitation of UpdateBlock map prevents more than 2 longs from being
  114.     // set in the block map. This means you shouldn't have more than 33 keyword blocks
  115.     // set or you could fail and corrupt your blocks. (Of course this is 1052 characters)
  116.     virtual    void    UpdateBlockMap(KeywordPageH thePage, short firstBlock, short count,
  117.                                         Boolean turnOn);
  118. };
  119.